package Hot_100;
/*
    给你一个 32 位的有符号整数 x ，返回将 x 中的数字部分反转后的结果。
    如果反转后整数超过 32 位的有符号整数的范围 [−2^31,  2^31 − 1] ，就返回 0。
    假设环境不允许存储 64 位整数（有符号或无符号）。
    链接：https://leetcode.cn/problems/reverse-integer
* */

import org.junit.Test;

/*
    [−2^31,  2^31 − 1]是int的取值范围
    题目中提到：如果反转后超过范围就返回0，所以使用的数据类型应该是表示范围更大的long;
    但是题目规定了不能使用long，如果是直接用long，这个题就没有意义了...
    主要是怎么判断溢出的情况
    负数的求模和正数差不多,先看成正数求模之后，加上负号
* */
public class T7_reverse {
    @Test
    public void test() {
        System.out.println(-11 % 10);
        System.out.println(reverse(123));
    }

    /**
     * 法2: 每次模10取个位数，然后重新拼进去
     * 注意重新凑的数可能会溢出最大or最小值，所以在*10之前需要先判断是否溢出
     */
    public int reverse(int x) {
        int res = 0, yu;
        while (x != 0) {
            yu = x % 10;
//            当前结果 res*10+yu>MAX_VALUE 或者 res*10>MAX_VALUE则应该终止
            if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && yu > 7)) {   //正数溢出  //7是2^31-1的个位对应的数
                return 0;
            }
            if (res < Integer.MIN_VALUE/10 || (res == Integer.MIN_VALUE/10 && yu < -8)) {  //负数溢出  //-8是-2^31的各位对应的是
                return 0;
            }
            res *= 10;
            res += yu;
            x /= 10;
        }
        //正常情况
        return res;
    }

    /**
     * 法1: 将Integer.MAX_VALUE转成字符串
     * 以后读入一个x的时候，就将x转字符串，然后再反转，并与Integer.MAX_VALUE对应的字符串作比较，如果大于说明溢出,返回0
     * 否则不溢出，再转成整数返回
     * 但是 String是没有reverse函数，只有StringBuffer or StringBuilder才有，所以类型的比较也比较麻烦
     * 而且还涉及到string转int的操作
     */
//    public int reverse1(int x) {
//        String max_value = String.valueOf(Integer.MAX_VALUE);
//        String xx = String.valueOf(x);
//        StringBuffer yy = new StringBuffer(xx);
//        StringBuffer reverse_yy = yy.reverse();
//    }
}